/* SPDX-License-Identifier: BSD-3-Clause
 *
 * Copyright(c) 2021 Intel Corporation. All rights reserved.
 */

#include <sof/audio/format.h>
#include <stdint.h>

#if CONFIG_COMP_VOLUME_WINDOWS_FADE

#define WINDOWS_FADE_LUT_SIZE 128
#define WINDOWS_FADE_LUT_STEP \
	Q_CONVERT_FLOAT(1.0 / (WINDOWS_FADE_LUT_SIZE - 1), 30)  /* Q2.30 */

/* Calculate power y = x^1.75, input and output are in Q2.30 format */

static const int16_t windows_fade_lookup[WINDOWS_FADE_LUT_SIZE] = {
	0x0000, 0x0007, 0x0017, 0x002f, 0x004d, 0x0072, 0x009d, 0x00cd,
	0x0104, 0x013f, 0x0180, 0x01c5, 0x0210, 0x025f, 0x02b3, 0x030c,
	0x0369, 0x03cb, 0x0431, 0x049b, 0x050a, 0x057d, 0x05f4, 0x066f,
	0x06ef, 0x0772, 0x07fa, 0x0885, 0x0914, 0x09a8, 0x0a3f, 0x0ada,
	0x0b78, 0x0c1b, 0x0cc1, 0x0d6b, 0x0e18, 0x0eca, 0x0f7f, 0x1037,
	0x10f3, 0x11b3, 0x1276, 0x133d, 0x1407, 0x14d4, 0x15a5, 0x167a,
	0x1752, 0x182d, 0x190c, 0x19ee, 0x1ad4, 0x1bbc, 0x1ca8, 0x1d98,
	0x1e8a, 0x1f80, 0x207a, 0x2176, 0x2276, 0x2379, 0x247f, 0x2588,
	0x2695, 0x27a4, 0x28b7, 0x29cd, 0x2ae6, 0x2c02, 0x2d22, 0x2e44,
	0x2f69, 0x3092, 0x31be, 0x32ec, 0x341e, 0x3553, 0x368a, 0x37c5,
	0x3903, 0x3a44, 0x3b87, 0x3cce, 0x3e18, 0x3f64, 0x40b4, 0x4207,
	0x435c, 0x44b4, 0x4610, 0x476e, 0x48cf, 0x4a33, 0x4b9a, 0x4d04,
	0x4e70, 0x4fe0, 0x5152, 0x52c7, 0x543f, 0x55ba, 0x5738, 0x58b8,
	0x5a3b, 0x5bc2, 0x5d4a, 0x5ed6, 0x6065, 0x61f6, 0x638a, 0x6521,
	0x66ba, 0x6856, 0x69f5, 0x6b97, 0x6d3c, 0x6ee3, 0x708d, 0x723a,
	0x73e9, 0x759b, 0x7750, 0x7907, 0x7ac1, 0x7c7e, 0x7e3e, 0x7fff,
};

static inline int32_t volume_pow_175(int32_t val)
{
	int32_t y0;
	int32_t y1;
	int32_t dx;
	int32_t c;
	int32_t y;
	int i;

	if (val == 0)
		return 0;

	i = Q_MULTS_32X32((int64_t)val, WINDOWS_FADE_LUT_SIZE - 1, 30, 0, 0);
	if (i >= WINDOWS_FADE_LUT_SIZE - 1)
		return Q_CONVERT_FLOAT(1, 30);

	y0 = windows_fade_lookup[i];
	y1 = windows_fade_lookup[i + 1];
	c = (y1 - y0) * (WINDOWS_FADE_LUT_SIZE - 1); /* Q1.15 */
	dx = val - i * WINDOWS_FADE_LUT_STEP; /* Q2.30 */
	y = Q_SHIFT_LEFT(y0, 15, 30) + Q_MULTSR_32X32((int64_t)dx, c, 30, 15, 30);
	return y;
}

#endif /* CONFIG_COMP_VOLUME_WINDOWS_FADE */

